/*
 * Licensed Materials - Property of tenxcloud.com
 * (C) Copyright 2018 TenxCloud. All Rights Reserved.
 * 2018-06-13  @author lizhen
 */

package utility

type Step interface {
	Exec() error
	RollBack() error
}

type Transaction interface {
	Exec(step Step) error
	RollBack() []error
}

func BeginTransaction() Transaction {
	return &transaction{
		steps: make([]Step, 0),
	}
}

type transaction struct {
	steps []Step
}

func (t *transaction) Exec(step Step) error {
	if err := step.Exec(); err != nil {
		return err
	}
	t.steps = append(t.steps, step)
	return nil
}

func (t *transaction) RollBack() []error {
	count := len(t.steps)
	errs := make([]error, 0)
	for i := count - 1; i >= 0; i-- {
		if err := t.steps[i].RollBack(); err != nil {
			errs = append(errs, err)
		}
	}
	if len(errs) > 0 {
		return errs
	}
	return nil
}
